#include "brightness_detect.h"
#include "brightness_sensor_mode.h"
#include "systime.h"
#include "adc_driver.h"
#include "brightness_custom.h"
#include "indicator.h"
#include "shell_color_selector.h"

#define LIGHT_DET_UPDATE_MS 20

#define PT_FILITER_TIMES 10

// 根据光敏二极管及原理图的设计，光照度越大(越亮)，采集的电压越小
// DARK阈值对应于，光照度为桌面照度50lux（墙面21 lux）时，photoD的电压值。对应电阻值为330K
// DIM阈值对应于，光照度为150 lux(墙面62 lux)时，photoD的电压值

// photoD阈值--单位，ADC分辨率
#define PHOTOD_DEFAULT_THRESHOLD_BLACK 939 // 150 lux
#define PHOTOD_DEFAULT_THRESHOLD_WHITE 832 // 150 lux

typedef enum
{
    STATE_INITIALIZING,      // 初始化状态
    STATE_DETECT_BRIGHTNESS, // 正在检测光线强度
    STATE_VALID_RESULT,
    STATE_CONFIRM_BRIGHTNESS,

} brightness_detect_state_e;

typedef enum
{
    RUN_STATE_INIT,
    RUN_STATE_NORMAL,
} run_state_e;

static struct
{
    timestamp_t time;
    brightness_detect_state_e state;
    uint8_t is_brightness_satisfied; // 环境光检测结果，TRUE--黑暗程度满足设定值  FALSE--不满足
    uint8_t cnt;
    uint16_t threshold; // 单位，ADC分辨率
} brightness_detect_ctx;

static struct
{
    timestamp_t update_timeout; // 亮度传感器状态更新的超时时间
    run_state_e run_state;
    brightness_sensor_mode_e mode;           // 传感器模式
    uint8_t is_brightness_sensor_valid;      // TRUE--光感有效，FALSE--光感无效
    uint8_t is_brightness_detection_enabled; // 表示是否启用光线强度检测
} brightness_sensor_state_t;

static void brightness_sensor_state_update(void);
static void brightness_detection_task(void);
static void get_brightness_threshold(uint16_t *threshold);
static uint8_t brightness_detect_algorlthm(uint16_t threshold);

void brightness_detect_init(void)
{

    brightness_detect_ctx.state = STATE_INITIALIZING;
    brightness_detect_ctx.is_brightness_satisfied = FALSE;
    brightness_detect_ctx.cnt = 0;
    brightness_detect_ctx.threshold = PHOTOD_DEFAULT_THRESHOLD_WHITE; // 默认白色Dark

    brightness_sensor_state_t.run_state = RUN_STATE_INIT;
    brightness_sensor_state_t.mode = BRIGHTNESS_DEFAULT;
    brightness_sensor_state_t.is_brightness_sensor_valid = TRUE; // 默认光敏有效
    brightness_sensor_state_t.is_brightness_detection_enabled = OFF;

    if (get_shell_color() == SHELL_COLOR_WHITE)
    { // 白色外壳
        printf("write shell brightness threshold: %d \r\n", PHOTOD_DEFAULT_THRESHOLD_WHITE);
    }
    else
    {
        printf("black shell brightness threshold: %d \r\n", PHOTOD_DEFAULT_THRESHOLD_BLACK);
    }
}

void brightness_detect_task(void)
{
    brightness_sensor_state_update();
    brightness_detection_task();
}

static void brightness_sensor_state_update(void)
{
    switch (brightness_sensor_state_t.run_state)
    {
    case RUN_STATE_INIT:
        brightness_sensor_state_t.is_brightness_detection_enabled = OFF;
        relative_time_add_ms(&brightness_sensor_state_t.update_timeout, LIGHT_DET_UPDATE_MS); // 解决依赖关系，确保光照设置旋钮位置检测完成
        brightness_sensor_state_t.run_state = RUN_STATE_NORMAL;
        break;
    case RUN_STATE_NORMAL:
        if (is_relative_time_timeout(&brightness_sensor_state_t.update_timeout))
        {
            brightness_sensor_state_t.mode = get_brightness_sensor_mode();
            if (BRIGHTNESS_VAC_MODE == brightness_sensor_state_t.mode || BRIGHTNESS_SENSOR_DISABLED == brightness_sensor_state_t.mode)
            { // 光感无效
                brightness_sensor_state_t.is_brightness_sensor_valid = FALSE;
            }
            else
            {
                brightness_sensor_state_t.is_brightness_sensor_valid = TRUE;
            }
            brightness_sensor_state_t.is_brightness_detection_enabled = ON;
            relative_time_add_ms(&brightness_sensor_state_t.update_timeout, LIGHT_DET_UPDATE_MS);
        }
        break;

    default:
        break;
    }
}

static void brightness_detection_task(void)
{
    switch (brightness_detect_ctx.state)
    {
    case STATE_INITIALIZING:
        if (brightness_sensor_state_t.is_brightness_detection_enabled)
        {
            brightness_detect_ctx.state = STATE_DETECT_BRIGHTNESS;
        }
        break;
    case STATE_DETECT_BRIGHTNESS:
        if (!brightness_sensor_state_t.is_brightness_sensor_valid)
        { // 光感无效
            brightness_detect_ctx.is_brightness_satisfied = TRUE;
            brightness_detect_ctx.state = STATE_VALID_RESULT;
            relative_time_add_ms(&brightness_detect_ctx.time, LIGHT_DET_UPDATE_MS);
        }
        else if (!is_indicator_bright())
        { // 指示灯处于关闭状态
            relative_time_add_ms(&brightness_detect_ctx.time, LIGHT_DET_UPDATE_MS);
            brightness_detect_ctx.state = STATE_CONFIRM_BRIGHTNESS;
        }
        break;
    case STATE_CONFIRM_BRIGHTNESS:
        if (is_indicator_bright()) // LED处于不关闭状态---
        {
            brightness_detect_ctx.state = STATE_DETECT_BRIGHTNESS;
        }
        else if (is_relative_time_timeout(&brightness_detect_ctx.time))
        {
            get_brightness_threshold(&brightness_detect_ctx.threshold);
            brightness_detect_ctx.is_brightness_satisfied = brightness_detect_algorlthm(brightness_detect_ctx.threshold);
            brightness_detect_ctx.state = STATE_DETECT_BRIGHTNESS;
        }
        break;
    case STATE_VALID_RESULT:
        if (is_relative_time_timeout(&brightness_detect_ctx.time))
        {
            if (brightness_sensor_state_t.is_brightness_sensor_valid)
            { // 光感有效
                brightness_detect_ctx.state = STATE_DETECT_BRIGHTNESS;
            }
            relative_time_add_ms(&brightness_detect_ctx.time, LIGHT_DET_UPDATE_MS);
        }
        break;

    default:
        break;
    }
}

static void get_brightness_threshold(uint16_t *threshold)
{
    uint16_t temp_threshold;

    shell_color_e shell_color = get_shell_color();
    if (shell_color == SHELL_COLOR_WHITE)
    { // 白色外壳
        temp_threshold = PHOTOD_DEFAULT_THRESHOLD_WHITE;
    }
    else
    {
        temp_threshold = PHOTOD_DEFAULT_THRESHOLD_BLACK;
    }

    brightness_sensor_mode_e position = get_brightness_sensor_mode();
    if (BRIGHTNESS_DEFAULT == position)
    {
        *threshold = temp_threshold;
    }
    else if (BRIGHTNESS_CUSTOM == position)
    {
        if (!read_brightness_custom_value(threshold))
        { // FLASH存储的值读取失败
            *threshold = temp_threshold;
        }
    }
}

static uint8_t brightness_detect_algorlthm(uint16_t threshold)
{
    uint8_t res = FALSE;

    uint16_t photoD = get_photoD_val();
    if (photoD >= threshold)
    { // 光照度越大(越亮)，采集的电压越小
        brightness_detect_ctx.cnt += (brightness_detect_ctx.cnt >= PT_FILITER_TIMES) ? 0 : 1;
        if (brightness_detect_ctx.cnt >= PT_FILITER_TIMES)
        {
            res = TRUE;
        }
    }
    else
    {
        brightness_detect_ctx.cnt = 0;
    }

    return res;
}

uint8_t is_brightness_satisfy(void)
{
    return brightness_detect_ctx.is_brightness_satisfied;
}
